package com.sl.common.config;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.sl.common.ResponseData;
import com.sl.common.exception.GlobalErrorCodeEnum;
import com.sl.common.exception.SchemeNotFoundException;
import com.sl.common.exception.internal.DataParseException;
import com.sl.common.exception.model.ModelCalculationException;
import com.sl.common.exception.model.ModelInputException;
import com.sl.common.exception.model.ModelResultParseException;
import com.sl.common.exception.model.ModelSaveException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.util.RequestUtil;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestNotUsableException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import org.springframework.web.util.ContentCachingRequestWrapper;

import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.util.Map;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(ModelInputException.class)
    public ResponseData<Void> handleModelInputException(ModelInputException e) {
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }

    @ExceptionHandler(SchemeNotFoundException.class)
    public ResponseData<Void> handleSchemeNotFoundException(SchemeNotFoundException e) {
        log.error("方案查询失败，原因：{}",
                e.getMessage()
        );
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }

    @ExceptionHandler(ModelCalculationException.class)
    public ResponseData<Void> handleModelCalculationException(ModelCalculationException e) {
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }

    @ExceptionHandler(ModelResultParseException.class)
    public ResponseData<Void> handleModelCalculationException(ModelResultParseException e) {
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }

    @ExceptionHandler(DataParseException.class)
    public ResponseData<Void> handleModelCalculationException(DataParseException e) {
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }
    @ExceptionHandler(ModelSaveException.class)
    public ResponseData<Void> handleModelCalculationException(ModelSaveException e) {
        return ResponseData.error(e.getErrorCode() , e.getMessage() );
    }

    @ExceptionHandler(Exception.class)
    public ResponseData<Void> handleGlobalException(HttpServletRequest httpRequest, Exception e) {
        if(e instanceof NoResourceFoundException || e instanceof AsyncRequestNotUsableException){
            return null;
        }
        else {
            if(httpRequest!=null){
                // 包装请求使其可重复读取
                ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(httpRequest);
                String url = wrappedRequest.getRequestURI().substring(wrappedRequest.getContextPath().length());
                //读取参数
                Map<String,String[]> params = wrappedRequest.getParameterMap();
                String paramsStr= "";
                if(params!=null){
                    paramsStr = JSONUtil.toJsonStr(params);
                }
                log.error("API请求异常 - URL: {} | Params: {} ",
                        url,
                        paramsStr);
            }
            //打印输出到控制台
            e.printStackTrace();
            return ResponseData.error(GlobalErrorCodeEnum.INTERNAL_SERVER_ERROR , e.getMessage() );
        }
    }
}